package ru.spb.osll.myfit.chart;

import org.apache.log4j.Logger;
import ru.spb.osll.myfit.server.chart.*;
import ru.spb.osll.myfit.util.MyFitProperties;
import ru.spb.osll.myfit.util.parser.ILogParser;
import ru.spb.osll.myfit.util.parser.IResultSection;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

/**
 * User: Artem Bukhonov
 * Email: nerzhulart@gmail.com
 */
public abstract class AbstractChartsBuilder implements ChartsBuilder {
  private static Logger log = Logger.getLogger(AbstractChartsBuilder.class);

  private static final ChartXMLSerializer CHART_XML_SERIALIZER = new ChartXMLSerializer();
  private static final LogReader LOG_READER = new LogReader();
  private final String m_chartDirectory = MyFitProperties.getTestDirectory() + File.separator + "charts";


  private List<ChartRenderData> m_charts = new ArrayList<ChartRenderData>();
  private String m_logFilename = MyFitProperties.getLogFile();
  //private ChartRenderer m_renderer = new BasePngChartRenderer();
  //private ChartSaver m_chartSaver = new FileChartSaver(MyFitProperties.getTestDirectory());
  private List<ChartWriter> m_chartWriters = new ArrayList<ChartWriter>() {{
    add(new PngChartWriter(m_chartDirectory));
    add(new XMLChartWriter(m_chartDirectory));
  }};

  protected void addChart(ChartRenderData renderData) {
    m_charts.add(renderData);
  }

  /*
  This method allows to obtain data from log using specified parser
   */

  protected List<? extends IResultSection> getResults(ILogParser parser) throws IOException {
    return LOG_READER.read(m_logFilename, parser);
  }

  /*
  Override this method to implement your logic of charts generating. In this method you have to create CharRenderData
  instances that contains all information about your charts and add them using addChart method
   */
  protected abstract void generateCharts(List<? extends IResultSection> results) throws IOException;

  protected abstract ILogParser getLogParser();

  @Override
  public void doDrawCharts() throws IOException {
    generateCharts(getResults(getLogParser()));
    saveCharts();
  }

  private void checkAndCreateChartDirectory(String chartDirectoryPath){
    File chartDirectory = new File(chartDirectoryPath);
    if(!chartDirectory.exists()){
      chartDirectory.mkdir();
    }
  }

  protected void saveCharts() throws IOException {
//    if (m_renderer == null) {
//      throw new IllegalStateException("Chart renderer must be specified in generateCharts overridden method");
//    }
//    if (m_chartSaver == null) {
//      throw new IllegalStateException("Chart saver must be specified in generateCharts overridden method");
//    }
    checkAndCreateChartDirectory(m_chartDirectory);
    int i = 1;
    for (ChartRenderData data : m_charts) {
      ChartSaveInfo info = new ChartSaveInfo(data.getName(), i++);
      for(ChartWriter writer : m_chartWriters) {
        try {
          writer.write(data, info);
        } catch (IOException e) {
          log.error(writer.getClass().getName() + " failed to write chart " + data.getName(), e);
          throw e;
        }
      }
    }
  }
}
